package com.example.ossdemo.domain;

import com.aliyun.oss.*;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.aliyun.oss.model.OSSObject;

import java.io.*;
import java.net.URL;
import java.util.*;
import java.util.zip.Adler32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class Demo {
    /**
     * zip文件压缩
     * @param inputFile 待压缩文件夹/文件名
     * @param outputFile 生成的压缩包名字
     */

    public static void ZipCompress(String inputFile, String outputFile) throws Exception {
        //创建zip输出流
        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(outputFile));
        //创建缓冲输出流
        BufferedOutputStream bos = new BufferedOutputStream(out);
        File input = new File(inputFile);
        compress(out, bos, input,null);
        bos.close();
        out.close();
    }
    /**
     * @param name 压缩文件名，可以写为null保持默认
     */
    //递归压缩
    public static void compress(ZipOutputStream out, BufferedOutputStream bos, File input, String name) throws IOException {
        if (name == null) {
            name = input.getName();
        }
        //如果路径为目录（文件夹）
        if (input.isDirectory()) {
            //取出文件夹中的文件（或子文件夹）
            File[] flist = input.listFiles();

            if (flist.length == 0)//如果文件夹为空，则只需在目的地zip文件中写入一个目录进入
            {
                out.putNextEntry(new ZipEntry(name + "/"));
            } else//如果文件夹不为空，则递归调用compress，文件夹中的每一个文件（或文件夹）进行压缩
            {
                for (int i = 0; i < flist.length; i++) {
                    compress(out, bos, flist[i], name + "/" + flist[i].getName());
                }
            }
        } else//如果不是目录（文件夹），即为文件，则先写入目录进入点，之后将文件写入zip文件中
        {
            out.putNextEntry(new ZipEntry(name));
            FileInputStream fos = new FileInputStream(input);
            BufferedInputStream bis = new BufferedInputStream(fos);
            int len;
            //将源文件写入到zip文件中
            byte[] buf = new byte[1024];
            while ((len = bis.read(buf)) != -1) {
                bos.write(buf,0,len);
            }
            bis.close();
            fos.close();
        }
    }
    public static void main(String[] args) throws Throwable {
        String endpoint = "oss-cn-hangzhou.aliyuncs.com";
        // 从STS服务获取的临时访问密钥（AccessKey ID和AccessKey Secret）。
        String accessKeyId = "LTAI5tLE1vqPwywXY72qFL5q";
        String accessKeySecret = "dKiPD6O1jHNK33yKnPUlhfA7hSkWnq";
        // 从STS服务获取的安全令牌（SecurityToken）。
//        String securityToken = "yourSecurityToken";
        // 填写Bucket名称，例如examplebucket。
        String bucketName = "soec1";
        // 填写Object完整路径，例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
        String objectName = "soec/今日任务.md";
        // 填写Object完整路径，例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
        // 此处请填写多个Object完整路径，用于一次性获取多个Object的签名URL。
        String[] objectNameList = {"soec/今日任务.md","soec/6.png"};
        OSSUtil ossUtil = new OSSUtil();


        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        String substring = objectName.substring(objectName.lastIndexOf("/")+1);
        try {
            // 设置签名URL过期时间，单位为毫秒。
//            Date expiration = new Date(new Date().getTime() + 3600 * 1000);
            for(int i=0; i<objectNameList.length; i++){

                OSSObject ossObject = ossClient.getObject(bucketName, objectNameList[i]);
//                OSSObject ossObject = ossClient.getObject(bucketName, objectName);

                InputStream in = ossObject.getObjectContent();
                FileOutputStream fout=new FileOutputStream("d:\\yasuo"+"\\"+objectNameList[i].substring(objectNameList[i].lastIndexOf("/")+1));
//                FileOutputStream fout=new FileOutputStream("d:\\yasuo"+"\\"+substring);

                byte[]   b=new  byte[1024];
                int  t=in.read(b);
                while(t!=-1){
                    fout.write(b,0,t);
                    t=in.read(b);
                }

// 数据读取完成后，获取的流必须关闭，否则会造成连接泄漏，导致请求无连接可用，程序无法正常工作。
                fout.close();
                in.close();
                try {
                    ZipCompress("D:\\yasuo", "D:\\TestbyYTT.zip");
                } catch (Exception e) {
                    e.printStackTrace();
                }
                // 创建请求。
//                GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, objectNameList[i]);
//                // 设置HttpMethod为PUT。
//                generatePresignedUrlRequest.setMethod(HttpMethod.GET);
//                // 添加用户自定义元信息。
////                generatePresignedUrlRequest.addUserMetadata("author", "baymax");
////                // 设置ContentType。
////                generatePresignedUrlRequest.setContentType("application/txt");
//                generatePresignedUrlRequest.setExpiration(expiration);
//                // 生成签名URL。
//                URL url = ossClient.generatePresignedUrl(generatePresignedUrlRequest);
//                // 打印签名URL。
//                System.out.println("url = " + url);
            }
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}